<script setup>
import 'leaflet/dist/leaflet.css'
import '@supermap/iclient-leaflet/css/index'

import iServerConfigUrl from '/iServerConfig.json?url'

import { Edit, Search } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import $ from 'jquery'
import axios from 'axios'

import L from 'leaflet'
import '@supermap/iclient-leaflet'
import 'proj4leaflet'

import { inject } from 'vue'

const layerProps = {
    label: "label",
    children: "children"
};
const legendProps = {
    value: "id",
    label: "label",
    children: "children",
    img: "img"
};
</script>

<template>
    <el-button :icon="Edit" circle class="layerStatusBtn" @click="updateLayerPanelStatus" />
    <div class="layerStatusTitle">REST 地图 - 子图层控制显隐</div>
    <el-tree class="layerStatus" :props="layerProps" :data="subLayersData" node-key="id" ref="layerTree" show-checkbox @check="handleChecked"></el-tree>
    <el-button :icon="Search" circle class="layerLegendsBtn" @click="updateLegendPanelStatus" />
    <div class="layerLegendsTitle">REST 地图 - Legend 图例</div>
    <el-tree-v2 class="layerLegends" :props="legendProps" :data="layerLegendsData" ref="legendTree" :height="314">
        <template #default="{ node }">
            <span class="prefix">
                <el-image :src="node.data.img" /></span>
            <span>{{ node.label }}</span>
        </template>
    </el-tree-v2>
</template>

<script>
export default {
    name: 'MapOverlay',
    data() {
        return {
            restMapUrl: undefined,
            wmtsMapUrl: undefined,
            wmtsLayer: {},
            restLayer: {},
            subLayersData: [],
            treeNodeKeys: [],
            layerLegendsData: []
        }
    },
    mounted() {
        var map = inject('map');

        axios.get(iServerConfigUrl).then(res => {
            var iServerConfig = res.data;
            this.restMapUrl = `${iServerConfig.urls.MapOverlay.protocol}://${iServerConfig.urls.MapOverlay.hostname}:${iServerConfig.urls.MapOverlay.port}/${iServerConfig.urls.MapOverlay.restMapUrl}`;
            this.wmtsMapUrl = `${iServerConfig.urls.MapOverlay.protocol}://${iServerConfig.urls.MapOverlay.hostname}:${iServerConfig.urls.MapOverlay.port}/${iServerConfig.urls.MapOverlay.wmtsMapUrl}`;

            // 还原 map 显示范围
            if (map._size.x !== document.body.clientWidth) {
                $("#map")[0].style.width = '';
                map._size.x = document.body.clientWidth;
            }

            // 定义 4490 坐标系
            const CRS_4490 = new L.Proj.CRS("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs", {
                resolutions: [
                    0.04373046874998992,
                    0.02186523437499496,
                    0.01093261718749748,
                    0.00546630859374874,
                    0.00273315429687437,
                    0.001366577148437185,
                    0.0006832885742185925,
                    0.00034164428710929624,
                    0.00017082214355464812,
                    0.00008541107177732406,
                    0.00004270553588866203,
                    0.000021352767944331015,
                    0.000010676383972165508,
                    0.000005338191986082754,
                    0.000002669095993041377,
                    0.0000013345479965206884,
                    0.0000006672739982603442
                ],
                origin: [97.347425, 34.31465000089267]
            });
            map.options.crs = CRS_4490;
            map.flyTo([31.12, 104.48], 4);

            this.overlayMap(map);
        }).catch(err => {
            ElMessage.error(err.stack);
        });
    },
    methods: {
        // 地图叠加
        overlayMap(map) {
            // 添加 wmts 底图
            this.wmtsLayer = new L.supermap.WMTSLayer(this.wmtsMapUrl, {
                layer: "四川省90米DEM",
                style: "default",
                tilematrixSet: "Custom_四川省90米DEM",
                format: "image/png"
            });
            map.addLayer(this.wmtsLayer);

            // 子图层显隐控制
            this.getLayersInfo(map);

            // 加载图例信息
            this.loadLegendInfo();
        },

        // 获取图层信息
        getLayersInfo(map) {
            var that = this;
            L.supermap.layerInfoService(this.restMapUrl).getLayersInfo(function (getLayersInfoEventArgs) {
                var defaultCheckedKeys = [];
                if (getLayersInfoEventArgs.result) {
                    if (getLayersInfoEventArgs.result.subLayers) {
                        var index = 0;
                        for (var j = 0; j < getLayersInfoEventArgs.result.subLayers.layers.length; j++) {
                            var subLayer = getLayersInfoEventArgs.result.subLayers.layers[j];
                            var subLayers1 = {
                                id: index++,
                                label: subLayer.caption,
                                checked: subLayer.visible,
                                children: []
                            };
                            that.treeNodeKeys[j] = new Array();
                            if (subLayers1.checked) {
                                defaultCheckedKeys[defaultCheckedKeys.length] = subLayers1.id;
                            }
                            if (subLayer.subLayers.layers !== undefined) {
                                for (var k = 0; k < subLayer.subLayers.layers.length; k++) {
                                    var tempSubLayer = subLayer.subLayers.layers[k];
                                    var child = {
                                        id: index++,
                                        label: tempSubLayer.name,
                                        checked: tempSubLayer.visible,
                                        children: [],
                                        subLayer: tempSubLayer,
                                        parent: subLayers1
                                    };
                                    that.treeNodeKeys[j].push(child.id);
                                    if (child.subLayer.visible) {
                                        defaultCheckedKeys[defaultCheckedKeys.length] = child.id;
                                    }
                                    subLayers1.children[k] = child;
                                }
                            }
                            that.subLayersData[j] = subLayers1;
                        }
                    }
                }

                // 加载子图层显示状态
                setTimeout(function () {
                    that.$refs.layerTree.setCheckedKeys(defaultCheckedKeys);
                }, 100);

                // 创建临时图层
                var layerStatusParameters = new SuperMap.SetLayerStatusParameters();
                for (var i = 0; i < that.subLayersData.length; i++) {
                    var subLayerData = that.subLayersData[i];
                    if (subLayerData.children !== undefined && subLayerData.children.length > 0) {
                        for (j = 0; j < subLayerData.children.length; j++) {
                            var subLayer = subLayerData.children[j].subLayer;
                            var layerStatus = new SuperMap.LayerStatus();
                            layerStatus.layerName = subLayer.name;
                            layerStatus.isVisible = eval(subLayer.visible);
                            layerStatusParameters.layerStatusList.push(layerStatus);
                        }
                    }
                }
                new L.supermap.layerInfoService(that.restMapUrl).setLayerStatus(layerStatusParameters, function (createTempLayerEventArgs) {
                    var tempLayerID = createTempLayerEventArgs.result.newResourceID;
                    that.restLayer = new L.supermap.tiledMapLayer(that.restMapUrl, { layersID: tempLayerID });
                    map.addLayer(that.restLayer);
                });
            });
        },

        // 加载图例信息
        loadLegendInfo() {
            axios.get(`${this.restMapUrl}.json`).then(res => {
                var bounds = res.data.bounds;
                axios.get(`${this.restMapUrl}/legend.json?bbox=${bounds.left},${bounds.bottom},${bounds.right},${bounds.top}`).then(res => {
                    var layerLegends = res.data.layerLegends;
                    var idIndex = 0;
                    for (let i = 0; i < layerLegends.length; i++) {
                        var layerLegend = layerLegends[i];
                        var legendNode = {
                            id: idIndex++,
                            label: layerLegend.layerCaption,
                            img: `data:image/png;base64,${layerLegend.legends[0].imageData}`,
                        };
                        var subLayerLegendNodes = [];
                        legendNode.children = subLayerLegendNodes;
                        if (layerLegend.subLayerLegends !== null && layerLegend.subLayerLegends !== undefined) {
                            var subLayerLegends = layerLegend.subLayerLegends;
                            for (let j = 0; j < subLayerLegends.length; j++) {
                                var subLayerLegend = subLayerLegends[j];
                                var legends = subLayerLegend.legends;
                                for (let k = 0; k < legends.length; k++) {
                                    var legend = legends[k];
                                    var subLegendNode = {
                                        id: idIndex++,
                                        label: legend.label,
                                        img: `data:image/png;base64,${legend.imageData}`,
                                        children: []
                                    };
                                    subLayerLegendNodes[subLayerLegendNodes.length] = subLegendNode;
                                }
                            }
                        }
                        this.layerLegendsData[this.layerLegendsData.length] = legendNode;
                    }
                    var legendExpandedKeys = [];
                    for (let i = 0; i < this.layerLegendsData.length; i++) {
                        legendExpandedKeys[legendExpandedKeys.length] = this.layerLegendsData[i].id;
                    }
                    this.$refs.legendTree.setData(this.layerLegendsData);
                    this.$refs.legendTree.setExpandedKeys(legendExpandedKeys);
                }).catch(err => {
                    console.log(err);
                });
            }).catch(err => {
                console.log(err);
            });
        },

        // 复选框点击事件
        handleChecked(node, checked) {
            node.checked = checked;
            if (node.subLayer !== undefined) {
                node.subLayer.visible = checked;
            }

            var checkedKeys = this.$refs.layerTree.getCheckedKeys(true);
            var layerIds = [];
            for (var i = 0; i < this.treeNodeKeys.length; i++) {
                var subLayerIds = [];
                var nodeKeys = this.treeNodeKeys[i];
                for (var j = 0; j < nodeKeys.length; j++) {
                    var subLayerId = checkedKeys.indexOf(nodeKeys[j]);
                    if (subLayerId !== -1) {
                        subLayerIds[subLayerIds.length] = j;
                    }
                }
                layerIds[i] = subLayerIds;
            }

            // 构建子图层显示条件
            var str = "[0:";
            for (var i = 0; i < layerIds.length; i++) {
                var subLayerIds = layerIds[i];
                if (subLayerIds.length > 0) {
                    for (var j = 0; j < subLayerIds.length; j++) {
                        str += i.toString() + "." + subLayerIds[j];
                        if (j < subLayerIds.length - 1) {
                            str += ",";
                        }
                    }
                    if (i < layerIds.length - 1) {
                        str += ",";
                    }
                }
            }
            if (str.endsWith(",")) {
                str = str.substring(0, str.length - 1);
            }
            str += "]";
            //当所有图层都不可见时
            if (str.length < 5) {
                str = "[]";
            }

            var map = this.restLayer._map;
            this.restLayer.remove();
            this.restLayer = undefined;
            this.restLayer = new L.supermap.tiledMapLayer(this.restMapUrl, { layersID: str });
            this.restLayer.addTo(map);
        },

        // 显示 / 隐藏子图层控制面板
        updateLayerPanelStatus() {
            var layerStatusTile = $(".layerStatusTitle")[0];
            var layerStatus = $(".layerStatus")[0];
            if (layerStatusTile.style.display !== 'none') {
                layerStatusTile.style.display = 'none';
                layerStatus.style.display = 'none';
            } else {
                layerStatusTile.style.display = 'block';
                layerStatus.style.display = 'block';
            }
        },

        // 显示 / 隐藏图例显示面板
        updateLegendPanelStatus() {
            var layerLegendsTitle = $(".layerLegendsTitle")[0];
            var layerLegends = $(".layerLegends")[0];
            if (layerLegendsTitle.style.display !== 'none') {
                layerLegendsTitle.style.display = 'none';
                layerLegends.style.display = 'none';
            } else {
                layerLegendsTitle.style.display = 'block';
                layerLegends.style.display = 'block';
            }
        }
    }
}
</script>

<style scoped>
.layerStatusBtn {
    position: absolute;
    z-index: 1001;
    right: 0px;
    margin: 20px;
    background-color: #6093c5;
    color: #ffffff;
    border-color: transparent;
}

.layerStatusTitle {
    position: absolute;
    z-index: 1000;
    width: 300px;
    right: 0px;
    background-color: #6093c5;
    text-align: center;
    margin: 20px;
    line-height: 32px;
    color: #ffffff;
    border-top-right-radius: 16px;
    border-top-left-radius: 16px;
    font-weight: 500;
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    font-size: 14px;
}

.layerStatus {
    overflow: auto;
    position: absolute;
    z-index: 999;
    width: 300px;
    height: 340px;
    right: 0px;
    background-color: azure;
    margin: 52px 20px 0px 0px;
    line-height: 26px;
}

.layerLegendsBtn {
    position: absolute;
    z-index: 1001;
    right: 0px;
    margin: 428px 20px 0px 0px;
    background-color: #6093c5;
    color: #ffffff;
    border-color: transparent;
}

.layerLegendsTitle {
    position: absolute;
    z-index: 1000;
    width: 300px;
    right: 0px;
    background-color: #6093c5;
    text-align: center;
    margin: 428px 20px 0px 0px;
    line-height: 32px;
    color: #ffffff;
    border-top-right-radius: 16px;
    border-top-left-radius: 16px;
    font-weight: 500;
    font-family: "Avenir", Helvetica, Arial, sans-serif;
    font-size: 14px;
}

.layerLegends {
    overflow: auto;
    position: absolute;
    width: 300px;
    height: 314px;
    z-index: 999;
    right: 0px;
    margin: 20px;
    margin: 460px 20px 0px 0px;
    background-color: azure;
    line-height: 26px;
}

.prefix {
    margin-right: 8px;
    width: 16px;
    height: 16px;
}
</style>